package com.sinosoft.common.encrypt.filter;

import com.sinosoft.common.encrypt.annotation.ApiEncrypt;
import com.sinosoft.common.encrypt.properties.ApiDecryptProperties;
import com.sinosoft.common.core.utils.StringUtils;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.annotation.Annotation;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 简化版加密过滤器
 */
@Slf4j
public class SimpleCryptoFilter implements Filter {

    private final ApiDecryptProperties properties;

    public SimpleCryptoFilter(ApiDecryptProperties properties) {
        this.properties = properties;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest servletRequest = (HttpServletRequest) request;
        HttpServletResponse servletResponse = (HttpServletResponse) response;
        
        try {
            // 检查是否为POST请求
            if (HttpMethod.POST.matches(servletRequest.getMethod())) {
                // 获取加密注解
                ApiEncrypt apiEncrypt = getApiEncryptAnnotation(servletRequest);
                boolean responseFlag = apiEncrypt != null && apiEncrypt.response();
                
                ServletRequest requestWrapper = null;
                ServletResponse responseWrapper = null;
                EncryptResponseBodyWrapper responseBodyWrapper = null;
                
                // 检查是否有加密标头
                String headerValue = servletRequest.getHeader(properties.getHeaderFlag());
                if (StringUtils.isNotBlank(headerValue)) {
                    // 请求解密
                    requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties);
                } else if (apiEncrypt != null) {
                    // 有注解但没有加密头，返回错误
                    servletResponse.setStatus(403);
                    servletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
                    servletResponse.getWriter().write("{error:没有访问权限，请联系管理员授权}");
                    return;
                }
                
                // 判断是否响应加密
                if (responseFlag) {
                    responseBodyWrapper = new EncryptResponseBodyWrapper(servletResponse, properties);
                    responseWrapper = responseBodyWrapper;
                }
                
                // 继续过滤器链
                chain.doFilter(
                    requestWrapper != null ? requestWrapper : servletRequest,
                    responseWrapper != null ? responseWrapper : servletResponse
                );
                
                // 处理加密响应
                if (responseBodyWrapper != null) {
                    servletResponse.reset();
                    String encryptContent = responseBodyWrapper.getEncryptContent(servletResponse, properties.getPublicKey(), properties.getHeaderFlag());
                    writeResponse(servletResponse, encryptContent);
                }
            } else {
                // 非POST请求直接放行
                chain.doFilter(request, response);
            }
        } catch (Exception e) {
            log.error("请求处理失败", e);
            servletResponse.setStatus(500);
            servletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
            servletResponse.getWriter().write("{\"error\":\"系统处理异常: " + e.getMessage() + "\"}");
        }
    }

    /**
     * 获取 ApiEncrypt 注解
     */
    private ApiEncrypt getApiEncryptAnnotation(HttpServletRequest servletRequest) {
        try {
            // 简化处理：根据URL路径判断是否需要加密
            String requestURI = servletRequest.getRequestURI();
            if (requestURI.contains("/api/test")) {
                // 模拟返回一个ApiEncrypt注解
                return new ApiEncrypt() {
                    @Override
                    public boolean response() {
                        return true;
                    }
                    
                    @Override
                    public Class<? extends Annotation> annotationType() {
                        return ApiEncrypt.class;
                    }
                };
            }
            return null;
        } catch (Exception e) {
            log.error("获取注解失败", e);
            return null;
        }
    }

    /**
     * 写入响应内容
     */
    private void writeResponse(HttpServletResponse response, String content) throws IOException {
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.getWriter().write(content);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
} 